package com.freemalll.merchant.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.freemalll.merchant.common.CommonEnum;
import com.freemalll.merchant.domain.dto.MerchantRateDetailDto;
import com.freemalll.merchant.domain.dto.MerchantRateDto;
import com.freemalll.merchant.domain.dto.coopManagement.AssetRateDetailEditDto;
import com.freemalll.merchant.domain.entity.MerMerchantRateManage;
import com.freemalll.merchant.mapper.MerMerchantRateManageMapper;
import com.freemalll.merchant.service.MerMerchantRateManageDetailService;
import com.freemalll.merchant.service.MerMerchantRateManageService;
import com.freemalll.merchant.service.coopManagement.MerAssetRateManageDetailService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务层实现。
 *
 * @author songshixiong
 * @since 2025-05-26
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class MerMerchantRateManageServiceImpl extends ServiceImpl<MerMerchantRateManageMapper, MerMerchantRateManage> implements MerMerchantRateManageService {

    @Resource
    private MerAssetRateManageDetailService assetRateManageDetailService;
    @Resource
    private MerMerchantRateManageDetailService merchantRateManageDetailService;


    @Override
    public List<MerchantRateDto> listByMerId(String merId, String sceneParentCategory) {
        sceneParentCategory = getSceneParentCategory(sceneParentCategory);
        List<MerchantRateDto> rateDtoList = baseMapper.listByMerIdAndScene(merId, sceneParentCategory);
        if (CollectionUtils.isEmpty(rateDtoList)) {
            return rateDtoList;
        }
        List<String> rateIds = rateDtoList.stream().map(MerchantRateDto::getMerRateId).collect(Collectors.toList());
        List<MerchantRateDetailDto> rateManageDetails = merchantRateManageDetailService.queryListInMerRateId(rateIds, CommonEnum.rateModel.APR.name());
        return getMerchantRateDtos(rateDtoList, rateManageDetails);
    }

    private static String getSceneParentCategory(String sceneParentCategory) {
        if (sceneParentCategory.equals(CommonEnum.sceneCategory.DJK.name())) {
            sceneParentCategory = CommonEnum.supportingScenariosType.GREAT_HEALTH.name();
        } else {
            sceneParentCategory = CommonEnum.supportingScenariosType.EDUCATION.name();
        }
        return sceneParentCategory;
    }

    private List<MerchantRateDto> getMerchantRateDtos(List<MerchantRateDto> rateDtoList, List<MerchantRateDetailDto> rateManageDetails) {
        Map<String, List<MerchantRateDetailDto>> map = rateManageDetails.stream()
                .collect(Collectors.groupingBy(MerchantRateDetailDto::getMerRateId));
        List<String> sourceList = rateDtoList.stream().map(MerchantRateDto::getSourceId).collect(Collectors.toList());
        List<MerchantRateDto> merchantRateDetailDtos = assetRateManageDetailService.selectInterestAndFeeModelBySourceIds(sourceList);
        Map<String, List<MerchantRateDto>> interestAndFeeModelMap = merchantRateDetailDtos.stream()
                .collect(Collectors.groupingBy(MerchantRateDto::getSourceId));
        for (MerchantRateDto vo : rateDtoList) {
            List<MerchantRateDetailDto> details = map.get(vo.getMerRateId());
            if (!CollectionUtils.isEmpty(details)) {
                populatePhaseData(vo, details);
            }
            List<MerchantRateDto> interestAndFeeModelDetails = interestAndFeeModelMap.get(vo.getSourceId());
            if (!CollectionUtils.isEmpty(interestAndFeeModelDetails)) {
                List<Map<String, Object>> mapList = interestAndFeeModelDetails.stream()
                        // 单个 DTO 转 Map，参数：是否忽略空值，key 转换策略（此处用默认）
                        .map(dto -> BeanUtil.beanToMap(dto, true, true))
                        .collect(Collectors.toList());
                vo.setSupportInterestAndFeeModelList(mapList);
            }
        }
        return rateDtoList;
    }

    private List<MerchantRateDto> queryListByMerId(String merId, String type, String sceneCategory) {
        sceneCategory = getSceneParentCategory(sceneCategory);
        List<MerchantRateDto> rateDtoList = baseMapper.listByMerId(merId, sceneCategory);
        if (CollectionUtils.isEmpty(rateDtoList)) {
            return rateDtoList;
        }
        List<String> rateIds = rateDtoList.stream().map(MerchantRateDto::getMerRateId).collect(Collectors.toList());
        List<MerchantRateDetailDto> rateManageDetails = merchantRateManageDetailService.queryListInMerRateId(rateIds, type);
        return getMerchantRateDtos(rateDtoList, rateManageDetails);
    }

    @Override
    public void populatePhaseData(MerchantRateDto vo, List<MerchantRateDetailDto> details) {
        for (MerchantRateDetailDto detail : details) {
            switch (detail.getTimes()) {
                case 3:
                    vo.setPhaseThere(detail);
                    break;
                case 6:
                    vo.setPhaseSix(detail);
                    break;
                case 9:
                    vo.setPhaseNine(detail);
                    break;
                case 12:
                    vo.setPhaseTwelve(detail);
                    break;
                case 18:
                    vo.setPhaseEighteen(detail);
                    break;
                case 24:
                    vo.setPhaseTwentyFour(detail);
                    break;
                case 36:
                    vo.setPhaseThirtySix(detail);
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void batchInsert(List<MerchantRateDto> rateDtoList, String merId) {
        if (CollectionUtils.isEmpty(rateDtoList)) {
            return;
        }
        List<String> rateIds = rateDtoList.stream().map(MerchantRateDto::getRateId).collect(Collectors.toList());
        List<AssetRateDetailEditDto> assetRateDetailEditDtos = assetRateManageDetailService.listByYear(rateIds);
        Map<String, List<AssetRateDetailEditDto>> map = assetRateDetailEditDtos.stream()
                .collect(Collectors.groupingBy(AssetRateDetailEditDto::getRateId));
        rateDtoList.forEach(item -> {
            MerMerchantRateManage convert = Convert.convert(MerMerchantRateManage.class, item);
            convert.setMerId(merId);
            convert.setEnableFlag(true);
            baseMapper.insert(convert);
            List<AssetRateDetailEditDto> detailEditDtoList = map.get(item.getRateId());
            merchantRateManageDetailService.batchInsert(detailEditDtoList, convert.getMerRateId());
        });
    }

    @Override
    public List<MerchantRateDto> listByMerIdIRR(String merId, String sceneCategory) {
        return this.queryListByMerId(merId, CommonEnum.rateModel.IRR.name(), sceneCategory);
    }
}
